package com.fastjars.generator.plugin;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.List;

/**
 * GenXmlDaoPlugin
 *
 * @author Brant Liu <br> 邮箱：<br>lbf1988@qq.com <br>日期：<br>2017/12/23
 * @version 1.0.0
 */
public class GenXmlDaoPlugin extends PluginAdapter {
    @Override
    public boolean validate(List<String> list) {
        return true;
    }

    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        XmlElement parentElement = document.getRootElement();
        // 数据库表名
        String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();

        parentElement.addElement(createDelete("delete",tableName));
        //新增count
        parentElement.addElement(createCount("count",tableName));
        //新增query
        parentElement.addElement(createQuery("query",tableName));
        //新增queryWithRowbounds
        return super.sqlMapDocumentGenerated(document, introspectedTable);
    }

    private XmlElement createBaseColumnList(String id,List<IntrospectedColumn> columns){
        XmlElement sql = new XmlElement("sql");
        sql.addAttribute(new Attribute("id", "Base_Column_List"));
        StringBuilder element = new StringBuilder();
        for(int i=0;i<columns.size();i++){
            IntrospectedColumn column = columns.get(i);
            element.append(column.getActualColumnName());
            if(i != (columns.size() - 1)){
                element.append(", ");
            }
            if( i > 0 && i % 10 == 0 ){
                element.append("\n\t");
            }
        }
        sql.addElement(new TextElement(element.toString()));
        return sql;
    }

    private XmlElement createDelete(String id,String tableName){
        XmlElement delete = new XmlElement("delete");
        delete.addAttribute(new Attribute("id",id));
        delete.addAttribute(new Attribute("parameterType", Long.class.getName()));
        StringBuilder deleteSql = new StringBuilder();
        deleteSql.append("delete from ");
        deleteSql.append(tableName);
        deleteSql.append(" where id in ");
        deleteSql.append("\n");
        deleteSql.append("\t<foreach item=\"item\" collection=\"array\" open=\"(\" separator=\",\" close=\")\">");
        deleteSql.append("\n");
        deleteSql.append("\t\t#{item}");
        deleteSql.append("\n");
        deleteSql.append("\t</foreach>");
        delete.addElement(new TextElement(deleteSql.toString()));
        return delete;
    }

    /**
     * 创建Count 根据ConditionExample条件查询语句
     * @param tableName 表名称
     * @return
     */
    private XmlElement createCount(String id, String tableName){
        XmlElement queryCnt = new XmlElement("select");
        queryCnt.addAttribute(new Attribute("id", id));
        queryCnt.addAttribute(new Attribute("parameterType", "com.fastjars.framework.mybatis.query.ConditionExample"));
        queryCnt.addAttribute(new Attribute("resultType", Integer.class.getName()));
        //组装queryCnt SQL映射
        StringBuilder queryCntSql = new StringBuilder();
        queryCntSql.append("select count(*) from ");
        queryCntSql.append(tableName);
        queryCntSql.append("\n");
        queryCntSql.append("\t<if test=\"_parameter != null\" >");
        queryCntSql.append("\n");
        queryCntSql.append("\t\t<include refid=\"conditionQuery.where\" />");
        queryCntSql.append("\n");
        queryCntSql.append("\t</if>");
        queryCnt.addElement(new TextElement(queryCntSql.toString()));
        return queryCnt;
    }

    /**
     * 创建根据ConditionExample条件查询结果集
     * @param id sql id
     * @param tableName 表名称
     * @return
     */
    private XmlElement createQuery(String id,String tableName){
        XmlElement query = new XmlElement("select");
        query.addAttribute(new Attribute("id", id));
        query.addAttribute(new Attribute("parameterType", "com.fastjars.framework.mybatis.query.ConditionExample"));
        query.addAttribute(new Attribute("resultMap", "BaseResultMap"));
        //组装queryCnt SQL映射
        StringBuilder querySql = new StringBuilder();
        querySql.append("select").append("\n");
        querySql.append("\t<if test=\"distinct\" >").append("\n");
        querySql.append("\t\tdistinct").append("\n");
        querySql.append("\t</if>").append("\n");
        querySql.append("\t<include refid=\"Base_Column_List\" />").append("\n");
        querySql.append("\tfrom ").append(tableName).append("\n");
        querySql.append("\t<if test=\"_parameter != null\" >").append("\n");
        querySql.append("\t\t<include refid=\"conditionQuery.where\" />").append("\n");
        querySql.append("\t</if>").append("\n");
        querySql.append("\t<if test=\"orderByClause != null\" >").append("\n");
        querySql.append("\t\torder by ${orderByClause}").append("\n");
        querySql.append("\t</if>").append("\n");
        querySql.append("\t<if test=\"limit != null\" >").append("\n");
        querySql.append("\t\t<if test=\"offset != null\" >").append("\n");
        querySql.append("\t\t\tlimit ${offset}, ${limit}").append("\n");
        querySql.append("\t\t</if>").append("\n");
        querySql.append("\t\t<if test=\"offset == null\" >").append("\n");
        querySql.append("\t\t\tlimit ${limit}").append("\n");
        querySql.append("\t\t</if>").append("\n");
        querySql.append("\t</if>");
        query.addElement(new TextElement(querySql.toString()));
        return query;
    }

    @Override
    public boolean sqlMapInsertElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean sqlMapUpdateByPrimaryKeyWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }
}
